package net.sinodata.smartframework.threadpool.base;

import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Description: 所有线程池后台服务的父类
 * 
 * @author: yinliangyun
 * @date: 2021-5-19
 */
public abstract class AbstractThreadPool extends Thread {
	
	private static final Logger logger = LoggerFactory.getLogger(AbstractThreadPool.class);
	
	private String pretendClass = this.getClass().getName();

	public String getPretendClass() {
		return pretendClass;
	}

	public void setPretendClass(String pretendClass) {
		this.pretendClass = pretendClass;
	}

	private ThreadPoolExecutor executor;

	private String threadPoolName = "";

	private String threadPoolCode = "";

	private int threadCount;

	private int sleepTime;

	private boolean workState = true;

	/** 线程处理任务开始时间 */
	private String runStartTime;

	/** 线程处理任务结束时间 */
	private String runEndTime;

	public AbstractThreadPool() {}

	/**
	 * Description: 初始化线程池
	 * 
	 * @param threadPoolName
	 * @param threadPoolCode
	 * @param threadCount
	 * @param runStartTime
	 * @param runEndTime
	 * @param sleepTime
	 */
	public void init(String threadPoolName, String threadPoolCode, int threadCount, String runStartTime,
			String runEndTime, int sleepTime) {
		this.executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(threadCount);
		this.threadPoolName = threadPoolName;
		this.threadPoolCode = threadPoolCode;
		this.threadCount = threadCount;
		this.runStartTime = runStartTime;
		this.runEndTime = runEndTime;
		this.sleepTime = sleepTime;
	}

	public void execute(Runnable runable) {
		this.executor.execute(runable);
	}

	public int getProcessingTaskCount() {
		return this.executor.getActiveCount();
	}

	public int getScheduledTaskCount() {
		return this.executor.getQueue().size();
	}

	/**
	 * 获取线程池状态
	 * 
	 * @return
	 */
	public int getThreadPoolState() {
		if (this.getState().equals(Thread.State.NEW)) {
			return ThreadStatusEnum.NEW.getValue();
		} else if (this.getState().equals(Thread.State.RUNNABLE)) {
			return ThreadStatusEnum.RUNNABLE.getValue();
		} else if (this.getState().equals(Thread.State.BLOCKED)) {
			return ThreadStatusEnum.BLOCKED.getValue();
		} else if (this.getState().equals(Thread.State.TERMINATED)) {
			return ThreadStatusEnum.TERMINATED.getValue();
		} else if (this.getState().equals(Thread.State.WAITING)) {
			return ThreadStatusEnum.WAITING.getValue();
		} else if (this.getState().equals(Thread.State.TIMED_WAITING)) {
			return ThreadStatusEnum.TIMED_WAITING.getValue();
		}
		return ThreadStatusEnum.TERMINATED.getValue();
	}

	/**
	 * 停止线程池
	 */
	public void stopThreadPool() {
		workState = false;
		executor.shutdown();
		while (!executor.isShutdown()) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				logger.error("AbstractThreadPool stopThreadPool Thread sleep InterruptedException" + "_" + e.getMessage(), e);
			}
		}
		this.interrupt();
	}

	/**
	 * 线程池是否繁忙
	 * 
	 * @return
	 */
	public boolean isBusy() {
		return this.executor.getQueue().size() > threadCount + 5;
	}

	/**
	 * 线程池是否在运行时间内运行
	 * 
	 * @return
	 */
	public boolean isRunTime() {
		Date curTime = Calendar.getInstance().getTime();// 当前时间
		String curDate = ThreadPoolUtils.formatDate(curTime, "yyyyMMdd");
		Date startTime = ThreadPoolUtils.parseDateValue(curDate + " " + runStartTime, "yyyyMMdd HH:mm:ss", curTime);
		Date endTime = ThreadPoolUtils.parseDateValue(curDate + " " + runEndTime, "yyyyMMdd HH:mm:ss", curTime);
		if (startTime.after(endTime)) {
			Calendar cal = Calendar.getInstance();
			cal.setTime(endTime);
			cal.add(Calendar.DAY_OF_MONTH, 1);
			endTime = cal.getTime();
		}
		if (curTime.after(startTime) && curTime.before(endTime)) {
			return true;
		} else {
			return false;
		}
	}

	public ThreadPoolExecutor getExecutor() {
		return executor;
	}

	public void setExecutor(ThreadPoolExecutor executor) {
		this.executor = executor;
	}

	public String getThreadPoolName() {
		return threadPoolName;
	}

	public void setThreadPoolName(String threadPoolName) {
		this.threadPoolName = threadPoolName;
	}

	public boolean isWorkState() {
		return workState;
	}

	public void setWorkState(boolean workState) {
		this.workState = workState;
	}

	public int getThreadCount() {
		return threadCount;
	}

	public void setThreadCount(int threadCount) {
		this.threadCount = threadCount;
	}

	public int getSleepTime() {
		return sleepTime;
	}

	public void setSleepTime(int sleepTime) {
		this.sleepTime = sleepTime;
	}

	public String getThreadPoolCode() {
		return threadPoolCode;
	}

	public void setThreadPoolCode(String threadPoolCode) {
		this.threadPoolCode = threadPoolCode;
	}

	public String getRunStartTime() {
		return runStartTime;
	}

	public void setRunStartTime(String runStartTime) {
		this.runStartTime = runStartTime;
	}

	public String getRunEndTime() {
		return runEndTime;
	}

	public void setRunEndTime(String runEndTime) {
		this.runEndTime = runEndTime;
	}

}
